#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <setjmp.h>
#include <time.h>
#include <signal.h>       /* for signal */  
#include <execinfo.h>     /* for backtrace() */  
#include <fcntl.h>
#include <unistd.h>

/*
 * int setjmp(jmp_buf env);  这个函数 将上下文 ，就是cpu和内存的信息保存到env中。
 *
 * 然后调用 void longjmp(jmp_buf env, int val); 的时候 跳转到使用env中的信息 ，恢复上下文。
 *
 *	如果是第一回调用setjmp 它会返回 0，如果是在 从longjmp 跳转过来的 ，那就返回 longjmp的参数 val，
 *	根据setjmp的返回值，就可以决定执行可能发生错误的代码还是直接跳过这段代码。
 */

jmp_buf buf;

banana() 
{
	printf("in banana()\n");
	longjmp(buf, 1);
	/* 以下代码不会被执行 */
	printf("you'll never see this, because:longjmp \n");
}

main()
{
	if (setjmp(buf)) {
		printf("back in main.\n");
	}
	else {
		printf("first time through.\n");
		banana();
	}
}

#if 0

first time through.
in banana()
back in main.

需要注意的地方是：保证局部变量在longjmp过程中一直保持它的值的惟一可靠方法是把它声明为volatile
(这适用于那些值在setjmp和longjmp返回之间会改变的变量)。

setjmp/longjmp最大的用途是错误恢复。只要还没有从函数中返回，一旦发现一个不可恢复的错误，
可以把控制转移到主输入循环，并从那里重新开始。

像goto一样，setjmp and longjmp 使得程序难以理解和调试。如果不是出于特殊需要，最好避免使用它们。

#endif
